Skip to content

[qwen] Drop fp32 LayerNorm casts in Qwen3.5 text model on ORT >= 1.26 - #361

Merged
xadupre merged 3 commits into
mainfrom
copilot/import-changes-and-add-fast-test
May 24, 2026
Merged

[qwen] Drop fp32 LayerNorm casts in Qwen3.5 text model on ORT >= 1.26#361
xadupre merged 3 commits into
mainfrom
copilot/import-changes-and-add-fast-test

Conversation

Copilot AI commented May 24, 2026

Copy link
Copy Markdown
Contributor

Ports microsoft/onnxruntime-genai#2101: Qwen35TextModel was forcing every RMSNorm to cast IO to fp32, inserting ~216 Cast nodes (108 to-fp32 + 108 to-fp16) around SkipSimplifiedLayerNormalization in a 24-layer build. Upstream measurements show +13% gen tps on RTX 5080 and +9% on Intel iGPU with output remaining structurally identical, so the casts are removed — but only when the runtime is recent enough.

Changes

  • modelbuilder/builders/qwen.py — gate the five layernorm_attrs["cast"] assignments (use_fp32, root_input, skip_input, output_0, output_3) in Qwen35TextModel.__init__ on the installed onnxruntime version. On ORT >= 1.26 (nightly) the assignments are dropped, matching upstream onnxruntime-genai#2101. On older ORT releases the explicit fp32 cast wrapping is preserved, since the native fp16 SkipSimplifiedLayerNormalization kernel loses precision across Qwen3.5's 36+ layers.
  • tests/fast/test_random_qwen3_5.py — add test_qwen3_5_fp16_no_layernorm_fp32_casts: builds a tiny fp16 Qwen3.5 ONNX model and walks the graph to assert no Cast-to-fp32 feeds, and no Cast-from-fp32 consumes, any SkipSimplifiedLayerNormalization op. Verified to fail (15 offending casts) when the removed assignments are reintroduced. The test is skipped when running on onnxruntime < 1.26.

Diff sketch

# Qwen35TextModel.__init__
self.layernorm_attrs["add_offset"] = 1

# Keep RMSNorm IO in the model's native dtype on ORT >= 1.26 (see
# onnxruntime-genai#2101); older ORT still needs the fp32 cast wrapping.
if _ort_version() < (1, 26):
    self.layernorm_attrs["cast"]["use_fp32"] = True
    self.layernorm_attrs["cast"]["root_input"] = True
    self.layernorm_attrs["cast"]["skip_input"] = True
    self.layernorm_attrs["cast"]["output_0"] = True
    self.layernorm_attrs["cast"]["output_3"] = True

Copilot AI changed the title [WIP] Import changes from ONNX Runtime PR 2101 and add fast test Drop fp32 LayerNorm casts in Qwen3.5 text model May 24, 2026
Copilot AI requested a review from xadupre May 24, 2026 15:06
@xadupre
xadupre marked this pull request as ready for review May 24, 2026 15:18
@github-actions

github-actions Bot commented May 24, 2026

Copy link
Copy Markdown

📂 Impacted Files

2 file(s) changed in this pull request:

🔵 modelbuilder/builders/qwen.py (+24 / -9)
🔵 tests/fast/test_random_qwen3_5.py (+59 / -0)

@github-actions github-actions Bot changed the title Drop fp32 LayerNorm casts in Qwen3.5 text model [qwen] Drop fp32 LayerNorm casts in Qwen3.5 text model May 24, 2026
@codecov

codecov Bot commented May 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 36.36364% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.89%. Comparing base (9f484f8) to head (94dc72d).

Files with missing lines Patch % Lines
modelbuilder/builders/qwen.py 36.36% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #361      +/-   ##
==========================================
- Coverage   79.96%   79.89%   -0.08%     
==========================================
  Files          25       25              
  Lines        7837     7843       +6     
==========================================
- Hits         6267     6266       -1     
- Misses       1570     1577       +7     
Flag Coverage Δ
fast-tests 79.89% <36.36%> (-0.08%) ⬇️
fast-tests-ort-nightly 79.84% <36.36%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@xadupre

xadupre commented May 24, 2026

Copy link
Copy Markdown
Owner

@copilot it seems it does not work if it does not use the nightly versions

Agent-Logs-Url: https://github.com/xadupre/mbext/sessions/f2603def-6691-4404-852c-0551265dc4f1

Co-authored-by: xadupre <22452781+xadupre@users.noreply.github.com>

Copilot AI commented May 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot it seems it does not work if it does not use the nightly versions

Gated the cast removal on onnxruntime >= 1.26 in 94dc72d — on older ORT releases the explicit fp32 cast wrapping is kept (the native fp16 SkipSimplifiedLayerNormalization kernel loses precision across Qwen3.5's 36+ layers). The new test is also skipped on ORT < 1.26.

Copilot AI changed the title [qwen] Drop fp32 LayerNorm casts in Qwen3.5 text model [qwen] Drop fp32 LayerNorm casts in Qwen3.5 text model on ORT >= 1.26 May 24, 2026
@xadupre
xadupre merged commit 14331f9 into main May 24, 2026
7 of 9 checks passed
@xadupre
xadupre deleted the copilot/import-changes-and-add-fast-test branch May 24, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

import changes from https://github.com/microsoft/onnxruntime-genai/pull/2101 and add fast test

2 participants